/***************************************************************************//**
 * $Id: serialport.h 4 2009-09-26 00:59:20Z kowalski.slawek $
 * Project Name : quicksms
 *
 * \file serialport.h this file contains ISerialPort class declaration.
 * \package quicksms
 * \author $Author: kowalski.slawek $
 * \version $Revision: 4 $
 *
 *  $URL: http://quicksms.googlecode.com/svn/trunk/serial/serialport.h $
 ******************************************************************************/
#ifndef SERIALPORT_H
#define SERIALPORT_H

#include "../pch.h"
#include "serialdefs.h"

/*****************************************************************************//**
 * \namespace serial
 * \brief this namespace groups objects for manipulating data over serial ports.
 ********************************************************************************/

namespace serial{


  /***************************************************************************//**
  * \class CSerialPort
  * \brief this class represents a serial port in objective manner.
  *
  * This class helps with manipulating data over serial ports
  * It allows to select baudrate, parity and flow control
  *
  *******************************************************************************/

  class ISerialPort
  {
    public:
      /*********************************************************************//**
	* \brief this CSerialPort constructor opens a port with name passed as
	*  parameter.
	*
	* \param[in] name name of file descriptor representing port to open.
	***********************************************************************/
      CSerialPort(QString &name);

      
      /*********************************************************************//**
       * \brief constructor which allows to more precisely set port
       * parameters.
       *
       * \param[in] pName port name
       * \param[in] pBaudrate port baud rate
       * \param[in] pFlow useful when needed specific flow control
       * \param[in] pParity port parity control
       *
       * This constructor allows for more spohisticated port opening.
       * It is possible to select correct port speed, parity and
       * flow control instead of just choosing device name.
       *
       ***********************************************************************/
      ISerialPort(const QString &pName,const serial::Baudrate &pBaudrate,const serial::Parity &pParity,
		  const serial::FlowControl &pFlow,const bool pOpen = 0,const ReadCallback readCallback);

		  
      /********************************************************************//**
       * \brief this function opens a port
       * \param[in] pName port filename
       * \return returns port state
       * \retval
       *
       *  If already open return value is Status::FILE_ALREADY_OPEN
       * and if invalid file path is passed return value is 
       * Status::FILE_NOT_FOUND
       *
       ************************************************************************/
      bool open(const QString &pName);


      /********************************************************************//**
       * \brief this function opens a port
       * \return returns port state
       * \retval
       *
       *  If already open return value is Status::FILE_ALREADY_OPEN
       * and if invalid file path is passed return value is
       * Status::FILE_NOT_FOUND
       *
       ************************************************************************/
      bool open();

    
      /*********************************************************************//**
       * \brief reopens an already open port.
       * 
       * It is a convienience function, which allows to reopen port e.g
       * when an I/O error occured. It will use last settings (port name parity
       * speed and flow control).
       ************************************************************************/
       bool reopen();

       
      /*********************************************************************//**
       * \brief closes a port.
       * \param[in] pForce set to true if you want to terminate pending tasks.
       * 
       * closes a port. If you forget to close, it will be done in destructor.
       ************************************************************************/
      bool close( bool pForce = 0);

      
      /*********************************************************************//**
       * \brief opens or closes port, depending on pState value.
       * \param[in] pState set true to open, close to close :-)
       *
       * 
       ************************************************************************/
      bool setOpened(const bool &pState);

      /*********************************************************************//**
       * \brief opens or closes port, depending on pState value.
       * \param[in] pState set true to open, close to close :-)
       *
       *
       ************************************************************************/
      bool isOpened(const bool &pState);
      
      
      /*********************************************************************//**
       * \brief sets port blocking mode.
       * \param[in] pState
       * 
       * if port is in blocking mode, then the readBuffer() call will block
       * thread until there is data to be read.
       ************************************************************************/
      bool setBlocking(const bool &pState);

      
      /*********************************************************************//**
       * \brief sets port blocking mode.
       * \param[in] pState
       *
       * if port is in blocking mode, then the readBuffer() call will block
       * thread until there is data to be read.
       ************************************************************************/
      bool isBlocking(const bool &pState);

      
      /*********************************************************************//**
       * \brief set port baud rate.
       * \param[in] pBaudrate port baudrate
       * \todo value checks!
       * 
       ************************************************************************/
      bool setBaudrate(const serial::Baudrate &pBaudrate);

      
      /*********************************************************************//**
       * \brief get port baud rate.
       * \param[out] pBaudrate port baudrate
       * \todo value checks!
       *
       ************************************************************************/
      bool getBaudrate(serial::baudrate &pBaudrate);

      
      /*********************************************************************//**
       * \brief sets flow control
       * \param[in] pFlow new flow control
       * 
       * 
       ************************************************************************/
      bool setFlowControl(const serial::FlowControl &pFlow);

      
      /*********************************************************************//**
       * \brief sets flow control
       * \param[in] pFlow new flow control
       *
       *
       ************************************************************************/
      bool getFlowControl(const serial::FlowControl &pFlow);
      
      
       /*********************************************************************//**
       * \brief sets port parity checking mode.
       * \param[in] pParity port parity.
       *
       * 
       ************************************************************************/
      bool setParity(const serial::Parity &pParity);

       /*********************************************************************//**
       * \brief sets port parity checking mode.
       * \param[in] pParity port parity.
       *
       *
       ************************************************************************/
      bool getParity(const serial::Parity &pParity);

      
      /*********************************************************************//**
       * \brief sets port filename.
       * \param[in] pName port name /path
       *
       * if path is non-empty and existant, then mName = pName.
       ************************************************************************/
       bool setFilename(const QString &pName);


      /*********************************************************************//**
       * \brief sets port filename.
       * \param[in] pName port name /path
       *
       * if path is non-empty and existant, then mName = pName.
       ************************************************************************/
       bool getFilename(const QString &pName);
       

      /*********************************************************************//**
       * \brief sets port filename.
       * \param[out] pStatus target Status field.
       * 
       *  Use it to retrieve information about port operating status.
       ************************************************************************/
       bool getStatus(serial::Status &status);
       

      /*********************************************************************//**
       * \brief sets read callback function.
       * \param[in] pCallback pointer to callback function
       *
       * Usable when you want to execute function as soon as data arrives.
       * If pointer is valid, it sets mReadCallback to pCallback
       ************************************************************************/
       bool setReadCallback( const serial::ReadCallback &pCallback);
       
       
      /*********************************************************************//**
       * \brief writes data from buffer to port.
       * \param[in] pBuffer location in memory where source data resides.
       * \param[in] pSize number of bytes to be written.
       *
       * writeBuffer writes equal pSize bytes from pBuffer to port.
       ************************************************************************/
      int writeBuffer(void *pBuffer, unsigned int pSize);

      
      /*********************************************************************//**
       * \brief reads data from port to buffer
       * \param[out] pBuffer location in memory where source data resides.
       * \param[in] pSize number of bytes to be read.
       * \param[in] pTimeout read timeout.
       * \return number of bytes that actually have been retrieved.
       *
       * readBuffer reads MAXIMUM pSize bytes from port and writes it into
       * buffer pointed by pBuffer. If timeout > 0 the function will wait
       * if there aren't any bytes to be read.
       ************************************************************************/
      int readBuffer(void *pBuffer, unsigned int pSize = 0, unsigned int pTimeout = 0);



      /*********************************************************************//**
       * \brief writes string to port.
       * \param[in] pStr source string.
       * 
       *  This is a convenience function handling string to byte-array conversion
       ************************************************************************/
      int sendString(const QString &pStr);


      /*********************************************************************//**
       * \brief writes QByteArray to port.
       * \param[in] pArr source array.
       *
       *  This is a convenience function handling Qt byte arrays.
       ************************************************************************/
      int sendByteArray(const QByteArray &pArr);

      
      /*********************************************************************//**
       * \brief reads string from port.
       * \param[in] pStr source string.
       * \param[in] pSize (optional) max bytes to be read.
       *
       *  This is a convenience function handling string to byte-array conversion
       ************************************************************************/
      int recieveString(QString &pStr, const unsigned int &pSize = 0);



      bool isOpened()
      {
	

      };
      
    private:
      
 
      int mBaudrate; ///< current baudrate setting
      
      bool mOpened; ///< is port opened?
      bool mIoError; ///< when I/O error occurs this is set to true.
      bool mBlocking; ///< if port is in blocking mode this is set to true.
      bool mIsOpened; ///< indicates whether port is in open state.
      bool mBusy; ///< informs whether are there any operations in progress
      bool 

      QString mName; ///< port name is saved here
      
      serial::Parity mParity; ///< current parity setting
      serial::FlowControl mFlow;///< actual flowcontrol setting
      serial::Status mStatus; ///< port status
      serial::ReadCallback mReadCallback; ///< pointer to function which will be executed
      ///< everytime when there is data in buffer.
      int mSignalHandler(int signal);
  }; // ISerialPort
}; //serial

#endif //SERIALPORT_H